﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Intelligent.OTC.Domain.Repositories;
using Intelligent.OTC.Domain.DataModel;
using Intelligent.OTC.Common;
using Intelligent.OTC.Common.Utils;

namespace Intelligent.OTC.Business
{
    public class DisputeTrackingService
    {
        public OTCRepository CommonRep { get; set; }

        /// <summary>
        /// get dispute datas
        /// </summary>
        /// <returns></returns>
        public IEnumerable<DisputeTrackingView> GetDisputeDatas()
        {
            string deal = AppContext.Current.User.Deal.ToString();
            string eid = AppContext.Current.User.EID.ToString();

            return CommonRep.GetQueryable<DisputeTrackingView>()
                .Where(m => m.Deal == deal && m.Collector == eid);
        }

        /// <summary>
        /// Get IssueReason,Status,CreateDate,Comments
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<string> GetDisputeById(int id) {
            List<string> lstDispute = new List<string>();

            try
            {
                Dispute dis = CommonRep.GetDbSet<Dispute>().Where(o => o.Id == id).FirstOrDefault();
                lstDispute.Add(Helper.CodeToEnum<DisputeReason>(dis.IssueReason).ToString().Replace("_", " "));
                lstDispute.Add(Helper.CodeToEnum<DisputeStatus>(dis.Status).ToString().Replace("_", " "));
                lstDispute.Add(dis.CreateDate.ToString("yyyy-MM-dd hh:mm:ss"));
                lstDispute.Add(dis.Comments);
                lstDispute.Add(dis.CustomerNum);
                lstDispute.Add(dis.Status);

                return lstDispute;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /// <summary>
        /// Get Dispute Tracking Datas
        /// </summary>
        /// <param name="disId"></param>
        /// <returns></returns>
        public IEnumerable<DisputeTracking> GetDisputeInvoiceDatas(int disId)
        {
            string cusNum = "";
            List<DisputeTracking> disTracking = new List<DisputeTracking>();

            try
            {
                //get dispute invoice
                List<DisputeInvoice> disInv = CommonRep.GetQueryable<DisputeInvoice>()
                                                .Where(o => o.DisputeId == disId).ToList();

                cusNum = CommonRep.GetQueryable<Dispute>()
                            .Where(o => o.Id == disId).Select(o=>o.CustomerNum).FirstOrDefault();

                //invoice aging
                List<InvoiceAging> invList = CommonRep.GetQueryable<InvoiceAging>()
                                                .Where(o => o.Deal == AppContext.Current.User.Deal
                                                    && o.CustomerNum == cusNum).ToList();

                Customer customer = CommonRep.GetQueryable<Customer>()
                                                .Where(o => o.Deal == AppContext.Current.User.Deal
                                                    && o.CustomerNum == cusNum).FirstOrDefault();

                foreach (var inv in disInv) {
                    InvoiceAging invoice = invList.Where(o => o.InvoiceNum == inv.InvoiceId).FirstOrDefault();
                    DisputeTracking distrack = new DisputeTracking();
                    distrack.InvoiceId = invoice.Id;
                    distrack.InvoiceNum = invoice.InvoiceNum;
                    distrack.LegalEntity = invoice.LegalEntity;
                    distrack.InvoiceDate = invoice.InvoiceDate;
                    distrack.CreditTerm = invoice.CreditTrem;
                    distrack.DueDate = invoice.DueDate;
                    distrack.PurchaseOrder = invoice.PoNum;
                    distrack.SaleOrder = invoice.SoNum;
                    distrack.RBO = invoice.MstCustomer;
                    distrack.InvoiceCurrency = invoice.Currency;
                    distrack.OriginalInvoiceAmount = invoice.OriginalAmt.ToString();
                    distrack.OutstandingInvoiceAmount = invoice.BalanceAmt;
                    distrack.DaysLate = new TimeSpan(AppContext.Current.User.Now.Ticks).Subtract(new TimeSpan(Convert.ToDateTime(invoice.DueDate).Ticks)).Duration().Days.ToString();
                    distrack.PtpDate = invoice.PtpDate;
                    distrack.InvoiceTrack = !String.IsNullOrEmpty(invoice.TrackStates) ? Helper.CodeToEnum<TrackStatus>(invoice.TrackStates).ToString().Replace("_", " ") : "";
                    distrack.Status = !String.IsNullOrEmpty(invoice.States) ? Helper.CodeToEnum<InvoiceStatus>(invoice.States).ToString() : "";
                    distrack.DocumentType = invoice.Class;
                    distrack.Comments = invoice.Comments;
                    distrack.CustomerNum = customer.CustomerNum;
                    distrack.CustomerName = customer.CustomerName;
                    distrack.OrderBy = invoice.OrderBy;
                    disTracking.Add(distrack);
                }

                return disTracking.AsQueryable();
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /// <summary>
        /// Get Dispute History Status Change
        /// </summary>
        /// <param name="disputeid"></param>
        /// <returns></returns>
        public IEnumerable<DisputeHis> GetDisputeStatusChange(int disputeid) {
            try
            {
                Dispute dis = CommonRep.GetQueryable<Dispute>()
                                    .Where(o => o.Id == disputeid).FirstOrDefault();

                List<DisputeHis> disHisList = CommonRep.GetQueryable<DisputeHis>()
                                                .Where(o => o.DisputeId == disputeid).OrderByDescending(o => o.HisDate).ToList();

                foreach(var dislist in disHisList){
                    dislist.Operator = dis.CreatePerson;
                    dislist.HisType = Helper.CodeToEnum<DisputeStatus>(dislist.HisType).ToString().Replace("_", " ");
                }

                return disHisList.AsQueryable();
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

        //save notes
        public void SaveNotes(int id, string Notes)
        {
            Dispute dis = CommonRep.GetDbSet<Dispute>()
                .Where(o=>o.Id == id).FirstOrDefault();
            dis.Comments = Notes;
            CommonRep.Commit();
        }

        /// <summary>
        /// update t_dispute status and insert t_dispute_his his_type
        /// </summary>
        /// <param name="id">dispute id</param>
        /// <param name="status">status</param>
        public void UpdateStatus(int id, string status)
        {
            DisputeHis disHis = new DisputeHis();
            List<DisputeHis> listDisHis = new List<DisputeHis>();

            try
            {
                Dispute dis = CommonRep.GetDbSet<Dispute>()
                                .Where(o => o.Id == id).FirstOrDefault();
                dis.Status = status;
                CommonRep.Commit();

                DisputeHis oldDisputeHis = CommonRep.GetDbSet<DisputeHis>()
                                            .Where(o => o.DisputeId == id).FirstOrDefault();

                //insert dispute_his
                disHis.DisputeId = id;
                disHis.HisType = status;
                disHis.HisDate = AppContext.Current.User.Now;
                disHis.EmailId = oldDisputeHis.EmailId;
                listDisHis.Add(disHis);
                CommonRep.AddRange<DisputeHis>(listDisHis);
                CommonRep.Commit();
            }
            catch (Exception ex) 
            {
                throw ex;
            }
        }


        public void SendDisputeMail(MailTmp mail)
        {
            List<string> cus = new List<string>();
            cus = mail.GetRelatedCustomers();
            if (cus.Count > 0)
            {
                string customer = string.Join(",", cus.ToArray());
           
                AssertUtils.ArgumentHasText(customer, "Customer number");

                //mail.MessageId = Guid.NewGuid().ToString();

                // 1. Add contact history(dispute)
                ContactHistory chis = new ContactHistory();
                chis.Deal = AppContext.Current.User.Deal;
                chis.LegalEntity = "";
                chis.CustomerNum = customer;
                chis.CollectorId = AppContext.Current.User.EID;
                chis.ContacterId = mail.To;
                chis.ContactDate = AppContext.Current.User.Now;
                chis.Comments = "";
                chis.ContactId = mail.MessageId;
                chis.ContactType = "Mail";
                CommonRep.Add(chis);

                CommonRep.Commit();
            }

            // 2. send mail
            MailService mailService = SpringFactory.GetObjectImpl<MailService>("MailService");
            mailService.SendMail(mail);
        }
    }
}
